//
//  ImageViewer.swift
//  YoruNeko
//
//  Created by Apple on 2021/6/30.
//

import SwiftUI


struct preferenceKey: PreferenceKey {
    static var defaultValue: Int = 0
    static func reduce(value: inout Int, nextValue: () -> Int) {
        
    }
}



struct PageTabViewStyleExampleView: View {
    @EnvironmentObject var modelData: ImageViewModelData
    var width: CGFloat = UIScreen.main.bounds.width
    var height: CGFloat = UIScreen.main.bounds.height
    var callback: ImageViewerCallback?
    
    @State var images: [UIImage] 
    
    @State var currScales: [CGFloat] = [CGFloat].init(repeating: CGFloat(1.0), count: 100)
    
    @State var currAngles: [Angle] = [Angle].init(repeating: .zero, count: 100)
    var customImages: [SingleImageView] {
        images.enumerated().map { index, element in
            SingleImageView(image: element, currScale: $currScales[index], lastScale: $currScales[index+50], currAngle: $currAngles[index], lastAngle: $currAngles[index+50])
        }
    }
    
    
    
    
    @State private var isEditing: Bool = true

    var imageSaverCallBack : ImageSaverCallback {
        ImageSaverCallback.init(callback: {
            self.isToastPresented = true
            YRNKLog("图片查看器", item: "图片已保存")
        })
        
    }

    class ImageSaverCallback:NSObject{
        
        private var callback:(()->Void)?
        init(callback:(()->Void)?) {
            self.callback = callback
        }
        
        /*
         (void)image:(UIImage *)image
             didFinishSavingWithError:(NSError *)error
                          contextInfo:(void *)contextInfo;
         */
        @objc func complete(image:UIImage,error:Error?,contextInfo:UnsafeMutableRawPointer?){
            callback?()
            
        }
    }

    @State var isSavePhotoAlertPresented = false
    @State var isToastPresented = false
    
    var body: some View {
        VStack {
            if isEditing {
                HStack{
                    ZStack{
                        HStack{
                            Button {
                                callback?.goBack()
                            } label: {
                                Image("delete-white")
                                    .resizable()
                                    .frame(width: width/15, height: width/15, alignment: .leading)
                                    .padding()
                                
                            }
                            
                            Spacer()
                            Button {
                                isSavePhotoAlertPresented = true
                            } label: {
                                Text("保存")
                                
                            }.alert(isPresented: $isSavePhotoAlertPresented, content: {
                                Alert(title: Text("是否保存至本地相册"),
                                      primaryButton: .default(Text("保存"), action: {
                                        YRNKSharedThreadPool.dispatchTask {
                                            UIImageWriteToSavedPhotosAlbum(images[modelData.index], self.imageSaverCallBack, #selector(ImageSaverCallback.complete(image:error:contextInfo:)), nil)
                                        }
                                      }),
                                      secondaryButton: .cancel(Text("取消"))
                                      )
                                        
                            })
                        }
                        HStack{
                            Spacer()
                            
                            Text((modelData.index+1).description + "/" + images.count.description)
                                .font(.title)
                                .foregroundColor(.white)
                            
                            Spacer()
                        }
                    }
                }
                .frame(width: width, height: height/15, alignment: .leading)
                .transition(.move(edge: .top))
                .animation(.easeInOut(duration: 0.4))
                .padding(.top,5)
            }
            
            Spacer()
            
            TabView(selection: $modelData.index) {
                ForEach(customImages.indices, id: \.self) { index in
                    Group{
                        customImages[index]
                            .preference(key: preferenceKey.self, value: index)
                            .onPreferenceChange(preferenceKey.self, perform: { _ in
                                self.currAngles = [Angle].init(repeating: .zero, count: 100)
                                self.currScales = [CGFloat].init(repeating: CGFloat(1.0), count: 100)
                            })
                            
                    }
                    
                }
            }
            .onTapGesture {
                self.isEditing = !self.isEditing
            }
            .frame(width: width, height: height*2/3, alignment: .center)
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            .zIndex(1)
            .toast(isPresenting: $isToastPresented, alert: {
                AlertToast(displayMode: .banner(.slide), type: .complete(Color.blue), title: "图片已保存")
            })
            
            Spacer()
            
            if isEditing {
                HStack{
                    Button(action: {
                        customImages[modelData.index].scaleChange(isUp: true)
                    }, label: {
                        VStack {
                            Image(systemName: "plus.magnifyingglass")
                            Text("放大")
                        }
                        .frame(width: width/5)
                    })
                    
                    Button(action: {
                        customImages[modelData.index].scaleChange(isUp: false)
                    }, label: {
                        VStack {
                            Image(systemName: "minus.magnifyingglass")
                            Text("缩小")
                        }
                        .frame(width: width/5)
                    })
                    
                    Text((currScales[modelData.index]*100).description.split(separator: ".")[0] + "%")
                        .frame(width: width/6)
                    
                    
                    Button(action: {
                        customImages[modelData.index].rotate(isCW: false)
                    }, label: {
                        VStack {
                            Image(systemName: "rotate.left")
                            Text("左旋90°")
                        }
                        .frame(width: width/5)
                        .foregroundColor(.white)
                        
                    })
                    
                    Button(action: {
                        customImages[modelData.index].rotate(isCW: true)
                    }, label: {
                        VStack {
                            Image(systemName: "rotate.right")
                            Text("右旋90°")
                        }
                        .frame(width: width/5)
                        .foregroundColor(.white)
                        
                    })
                }
                .foregroundColor(.white)
                .frame(width: width, height: height/15, alignment: .center)
                .offset(x: 0, y: -20)
                .transition(.move(edge: .bottom))
                .animation(.easeInOut(duration: 0.4))
            }
        }
        
        
        
    }
}

struct ImageViewer: View {
    var width: CGFloat = UIScreen.main.bounds.width
    var height: CGFloat = UIScreen.main.bounds.height
    var callback:ImageViewerCallback?
    @State var images: [UIImage] = []
    @State var isLoading = true
    var imageUrls: [ImageInfo]?
    var body: some View {
        //        ZStack{
        //            Color.black
        //            VStack{
        //                HStack{
        //                    Image("delete-white")
        //                        .resizable()
        //                        .frame(width: width/20, height: width/20)
        //                }
        //                .frame(width: width, height: height/6, alignment: .leading)
        //                Group{
        //                    image
        //                        .background(Color.white.opacity(0.5))
        //                }
        //                .frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
        //
        //            }
        //            .frame(width: width, height: height)
        //
        //
        //        }
        //        .ignoresSafeArea()
        
        ZStack{
            Color.black
            if !isLoading {
                PageTabViewStyleExampleView(callback: callback, images: images)
            }
            else {
                ProgressView.init().scaleEffect(CGSize.init(width: 1.6, height: 1.6)).foregroundColor(.white).shadow(color: .white, radius: 0, x: 0, y: 0)
            }
        }
        .ignoresSafeArea()
        .onAppear(perform: {
            load()
        })
            
    }
    
//    init(currentIndex: Int,imageUrls:[ImageInfo]?,callback:ImageViewerCallback? ){
//        self.imageUrls = imageUrls
//        //load()
//        self.index = currentIndex
//        self.callback = callback
//    }
//
    
    func load(){
        YRNKSharedThreadPool.dispatchTask(operation: {
            if imageUrls != nil {
                let images =  parseImage(from: imageUrls!)
                YRNKSharedThreadPool.dispatchUITask(ui_operation: {
                    self.images = images
                    self.isLoading = false
                })
            }
        }, priority: .HIGH)
    }

    /*
     TODO:
     目前无法加载svg格式的图片
     */
    func parseImage(from imageUrls:[ImageInfo])->[UIImage]{
        var images = [UIImage].init()
        for imgInfo in imageUrls{
            if let imgData = try? Data.init(contentsOf: imgInfo.url, options: .alwaysMapped){
                if let img = UIImage.init(data:imgData){
                    imgInfo.index = images.count
                    images.append(img)
                }
            }
        }
        return images
    }
    

}

struct ImageViewer_Previews: PreviewProvider {
    
    static let _imageUrls = [ImageInfo.init(urlStr: "https://hgc.ink/scutzone/img/index-bg.00b465be.jpeg", width: 60, height: 60),
                            ImageInfo.init(urlStr: "https://hgc.ink/scutzone/static/posts/images/19d207de-5c5b-40c5-b06a-cccf44ebb316.jpg", width: 60, height: 60),
                           ImageInfo.init(urlStr: "https://hgc.ink/scutzone/static/posts/images/19d207de-5c5b-40c5-b06a-cccf44ebb316.jpg", width: 60, height: 60),
                            ImageInfo.init(urlStr: "https://hgc.ink/scutzone/static/posts/images/19d207de-5c5b-40c5-b06a-cccf44ebb316.jpg", width: 60, height: 60),
                           ImageInfo.init(urlStr: "https://hgc.ink/scutzone/static/posts/images/19d207de-5c5b-40c5-b06a-cccf44ebb316.jpg", width: 60, height: 60),ImageInfo.init(urlStr: "https://hgc.ink/scutzone/static/posts/images/19d207de-5c5b-40c5-b06a-cccf44ebb316.jpg", width: 60, height: 60),ImageInfo.init(urlStr: "https://hgc.ink/scutzone/static/posts/images/19d207de-5c5b-40c5-b06a-cccf44ebb316.jpg", width: 60, height: 60)]
    
    static var imageUrls:[ImageInfo]{
        var imgUrls = [ImageInfo].init()
        for imgInfo in _imageUrls{
            if let info = imgInfo{
                imgUrls.append(info)
            }
        }
        return imgUrls
    }
    
    static var previews: some View {
        ImageViewer(callback: nil, imageUrls: imageUrls)
            .environmentObject(ImageViewModelData(with: 0))
    }
}


